package com.woniu108.person.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu108.carService.commons.log.AdminHistoryLog;
import com.woniu108.carService.commos.dto.StoreAdminDto;
import com.woniu108.carService.commos.dto.StoreAdminSimpleDto;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.JWTUtil;
import com.woniu108.carService.commos.util.RedisUtil;
import com.woniu108.carService.commos.util.StaticData;
import com.woniu108.person.form.AddStoreAdminForm;
import com.woniu108.person.form.ChangeStoreAdminForm;
import com.woniu108.person.form.ChangeStoreAdminPassForm;
import com.woniu108.person.form.StoreAdminLoginForm;
import com.woniu108.person.model.AdminInfo;
import com.woniu108.person.model.Store;
import com.woniu108.person.model.StoreAdmin;
import com.woniu108.person.param.AddStoreAdminParam;
import com.woniu108.person.param.ChangeStoreAdminParam;
import com.woniu108.person.param.ChangeStoreAdminPassParam;
import com.woniu108.person.param.StoreAdminLoginParam;
import com.woniu108.person.service.AdminInfoService;
import com.woniu108.person.service.StoreAdminService;
import com.woniu108.person.service.StoreService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */
@RestController
@RequestMapping("/storeAdmin")
@Api(tags = "门店管理员信息接口")
public class StoreAdminController {


    @Resource
    private StoreAdminService storeAdminService;
    @Resource
    private AdminInfoService adminInfoService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private StoreService storeService;

    public String getStoreAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String storeAdminId=JWTUtil.parseStoreAdminToken(refreshToken).get("storeAdminId").toString();
        return storeAdminId;
    }
    public String getAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String adminId=JWTUtil.parseAdminToken(refreshToken).get("adminId").toString();
        return adminId;
    }

    /**
     * 门店管理员账号密码登录
     * @param form 账号名称 密码
     * @param response
     * @return 登录返回门店管理员dto对象
     */
    @PostMapping("/storeAdminLogin")
    @ApiOperation("门店管理员账号密码登录")
    public Result<StoreAdminSimpleDto> storeAdminLogin(@RequestBody StoreAdminLoginForm form, HttpServletResponse response){
       StoreAdminLoginParam param = BeanUtil.toBean(form, StoreAdminLoginParam.class);
       StoreAdminSimpleDto dto=storeAdminService.storeAdminLogin(param);
        //更新双token
        Map<String, Object> map = BeanUtil.beanToMap(dto);
        HashMap<String,Object> accessBody=new HashMap<String,Object>();
        String random=new Snowflake(1,1).nextIdStr();
        accessBody.put("random",random);
        String accessToken= JWTUtil.createStoreAdminToken(accessBody,60);//短token,有效时间60分钟
        String refreshToken=JWTUtil.createStoreAdminToken(map,3*24*60);//长token，有效时间3天
        //保存长token到Redis
        redisUtil.setString(accessToken,refreshToken,3*24*60*60);
        //响应到前端,设置响应头,这里使用的是短token
        response.setHeader("token",accessToken);
        response.setHeader("Access-Control-Expose-Headers","token");
       return Result.getResult(StoreAdminSimpleDto.class).setData(dto).setMsg("门店管理员登录成功");
    }

    /**
     * 添加门店管理员账号，仅后端普通、超级管理员可执行
     * @param form 新增门店管理员账号信息 姓名 密码 管理门店编号(可为空,后期通过修改添加管理门店)
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/addStoreAdmin.api")
    @ApiOperation("添加门店管理员账号")
    @AdminHistoryLog
    public Result addStoreAdmin(@RequestBody AddStoreAdminForm form,@RequestHeader String token){
        String currentAdminId = this.getAdminId(token);
        if(ObjectUtil.isEmpty(currentAdminId)) throw new WoniuException("非管理员账号",10001);
        AdminInfo adminInfo = adminInfoService.getById(currentAdminId);
        if(adminInfo.getAdminState()!=StaticData.ADMIN_STATE_NORMAL) throw new WoniuException("管理员状态不正常",10001);
        AddStoreAdminParam param = BeanUtil.toBean(form, AddStoreAdminParam.class);
        StoreAdmin storeAdmin = BeanUtil.toBean(param, StoreAdmin.class);
        String random=new Snowflake(1,1).nextIdStr();
        storeAdmin.setStoreAdminId(random);
        storeAdmin.setStoreAdminState(StaticData.ADMIN_STATE_NORMAL);
        storeAdmin.setCreateTime(LocalDateTime.now());
        storeAdminService.save(storeAdmin);
        return Result.getResult().setMsg("新增门店管理员账号成功");
    }

    /**
     * 删除门店管理员，仅后端普通、超级管理员可执行
     * @param token
     * @param storeAdminId 门店管理员ID
     * @return result 接口是否正常访问到结果
     */
    @GetMapping("/deleteStoreAdmin.api")
    @ApiOperation("删除门店管理员账号")
    @ApiImplicitParam(name = "storeAdminId",value ="门店管理员ID" )
    @AdminHistoryLog
    public Result deleteStoreAdmin(@RequestHeader String token,String storeAdminId){
        String currentAdminId = this.getAdminId(token);
        if(ObjectUtil.isEmpty(currentAdminId)) throw new WoniuException("非管理员账号",10001);
        AdminInfo adminInfo = adminInfoService.getById(currentAdminId);
        if(adminInfo.getAdminState()!=StaticData.ADMIN_STATE_NORMAL) throw new WoniuException("管理员状态不正常",10001);
        StoreAdmin storeAdmin = storeAdminService.getById(storeAdminId);
        storeAdmin.setStoreAdminState(StaticData.ADMIN_STATE_DELETE);
        storeAdminService.updateById(storeAdmin);
        return Result.getResult().setMsg("删除门店管理员账号成功");
    }

    /**
     * 修改管理员账号信息(姓名、管理门店编号、状态)
     * @param form 门店编号、管理员姓名、管理员管理门店编号、管理员状态
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/changeStoreAdminInfo.st")
    @ApiOperation("修改管理员账号信息(姓名、管理门店编号、状态)")
    public Result changeStoreAdminInfo(@RequestBody ChangeStoreAdminForm form){
        ChangeStoreAdminParam param = BeanUtil.toBean(form, ChangeStoreAdminParam.class);
        StoreAdmin storeAdmin = storeAdminService.getById(param.getStoreId());
        if(ObjectUtil.isEmpty(storeAdmin)) throw new WoniuException("账号不存在",10001);
        if(param.getStoreAdminName()!=null) storeAdmin.setStoreAdminName(param.getStoreAdminName());
        if(param.getStoreId()!=null) storeAdmin.setStoreId(param.getStoreId());
        if(param.getStoreAdminState()!=null) storeAdmin.setStoreAdminState(param.getStoreAdminState());
        storeAdminService.updateById(storeAdmin);
        return Result.getResult().setMsg("修改信息成功");
    }

    /**
     * 修改门店管理员密码
     * @param form 两次旧密码输入，一次新密码输入
     * @param token
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/changeStoreAdminPass.st")
    @ApiOperation("修改门店管理员密码")
    public Result changeStoreAdminPass(@RequestBody ChangeStoreAdminPassForm form,@RequestHeader String token){
        ChangeStoreAdminPassParam param = BeanUtil.toBean(form, ChangeStoreAdminPassParam.class);
        if(!param.getOldPass().equals(param.getOldPassAgain())) throw new WoniuException("两次输入密码不一致",10001);
        String storeAdminId = this.getStoreAdminId(token);
        StoreAdmin storeAdmin = storeAdminService.getById(storeAdminId);
        if(!storeAdmin.getStoreAdminPass().equals(param.getOldPass())) throw new WoniuException("旧密码有误",10001);
        storeAdmin.setStoreAdminPass(param.getNewPass());
        storeAdminService.updateById(storeAdmin);
        return Result.getResult().setMsg("修改密码成功");
    }

    /**
     * 根据门店管理员编号获取门店管理员详细信息
     * @param storeAdminId 门店管理员ID
     * @return 门店管理员详细信息 编号、姓名、创建时间、管理门店编号、状态
     */
    @GetMapping("/getStoreAdminInfoById/{storeAdminId}.c")
    @ApiOperation("根据门店管理员编号获取门店管理员详细信息")
    @ApiImplicitParam(name = "storeAdminId",value ="门店管理员ID" )
    public Result<StoreAdminDto> getStoreAdminInfoById(@PathVariable("storeAdminId")String storeAdminId){
        StoreAdmin storeAdmin = storeAdminService.getById(storeAdminId);
        StoreAdminDto dto = BeanUtil.toBean(storeAdmin, StoreAdminDto.class);
        if(storeAdmin.getStoreId()!=null){
            Store store = storeService.getById(storeAdmin.getStoreId());
            dto.setStoreName(store.getStoreName());
        }else{
            dto.setStoreName("暂无管理门店");
        }
        return Result.getResult(StoreAdminDto.class).setData(dto);
    }

    /**
     * 获取所有门店管理员信息
     * @return List<StoreAdminDto> 门店管理员信息集合
     */
    @GetMapping("/listStoreAdmin.api")
    @ApiOperation("获取所有门店管理员信息")
    public Result<List<StoreAdminDto>> listStoreAdmin(){
        QueryWrapper<StoreAdmin> wrapper = new QueryWrapper<>();
        wrapper.ne("store_admin_state",StaticData.ADMIN_STATE_DELETE);
        List<StoreAdmin> storeAdmins = storeAdminService.list(wrapper);
        ArrayList<StoreAdminDto> dtos = new ArrayList<>();
        for (StoreAdmin storeAdmin : storeAdmins) {
            StoreAdminDto dto = BeanUtil.toBean(storeAdmin, StoreAdminDto.class);
            if(storeAdmin.getStoreId()!=null){
                Store store = storeService.getById(storeAdmin.getStoreId());
                dto.setStoreName(store.getStoreName());
            }else{
                dto.setStoreName("暂无管理门店");
            }
            dtos.add(dto);
        }
        return Result.newListInstance(StoreAdminDto.class).setData(dtos);
    }

    /**
     * 获取所有状态正常、未负责门店的门店管理员账号
     * @return List<StoreAdminDto> 门店管理员信息列表
     */
    @GetMapping("/listStoreAdminAllowChooseStore.api")
    @ApiOperation("获取所有状态正常、未负责门店的门店管理员账号")
    public Result<List<StoreAdminDto>> listStoreAdminAllowChooseStore(){
        QueryWrapper<StoreAdmin> wrapper = new QueryWrapper<>();
        wrapper.isNull("store_id");
        wrapper.eq("store_admin_state",StaticData.ADMIN_STATE_NORMAL);
        List<StoreAdmin> list = storeAdminService.list(wrapper);
        List<StoreAdminDto> dtos = new ArrayList<>();
        for (StoreAdmin storeAdmin : list) {
            StoreAdminDto dto = BeanUtil.toBean(storeAdmin, StoreAdminDto.class);
            dtos.add(dto);
        }

        return Result.newListInstance(StoreAdminDto.class).setData(dtos);
    }
}

